package ua.kharkov.khpi.tarasenko.bach.web.tag;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import ua.kharkov.khpi.tarasenko.bach.core.Constant;
import ua.kharkov.khpi.tarasenko.bach.core.LocalizedResourceManager;

/**
 * Tag for printing error message on jsp page.
 * 
 * @author oleksandr
 *
 */
public class PrintErrorTag extends SimpleTagSupport {
	private boolean detail = false;
	private String errorMessage;

	@Override
	public void doTag() throws JspException, IOException {

		PageContext pageContext = (PageContext) getJspContext();
		JspWriter out = pageContext.getOut();

		boolean isMessagePrinted = false;

		HttpServletRequest request = (HttpServletRequest) pageContext
				.getRequest();
		
		// Create LocalizedResourceManager to get localized error messages
		LocalizedResourceManager LRManager = getLocalizedResourceManager(request);

		out.print(LRManager.getMessage("print_error_tag_java.next_error_message"));
		out.print("<br /> <br />");
		out.print("<div id='errorMessage'>");
		if ((errorMessage != null) && (!errorMessage.isEmpty())) {

			out.print(errorMessage + "<br />");

			isMessagePrinted = true;
		} else {

			// If error is empty than look for error code and exception in
			// request
			Object errorCodeObj = request
					.getAttribute("javax.servlet.error.status_code");
			Object messageObj = request
					.getAttribute("javax.servlet.error.message");
			Object typeObj = request
					.getAttribute("javax.servlet.error.exception_type");

			String errorCode = null;
			String message = null;
			String type = null;

			if (errorCodeObj != null) {
				errorCode = errorCodeObj.toString();
				out.print(LRManager.getMessage("print_error_tag_java.error_code"));
				out.print(errorCode);
				out.print("<br />");
			}

			if (messageObj != null) {
				message = messageObj.toString();
				if ((errorCode != null) && (errorCode.equals("404"))) {
					out.print(LRManager.getMessage("print_error_tag_java.page_not_exist"));
					out.print(message);
				} else {
					out.print("Error message: " + message);
				}
				out.print("<br />");
			}

			if (detail) {

				if (typeObj != null) {
					type = typeObj.toString();
					out.print("Error class: " + type);
					out.print("<br />");
				}

				// Print stack trace of exception
				Object thrObj = request
						.getAttribute("javax.servlet.error.exception");
				Throwable thr = null;
				if (thrObj != null) {
					out.print("<div class='small_error_message'>");

					thr = (Throwable) thrObj;
					thr.printStackTrace(new PrintWriter(out));

					out.print("</div>");
				}
			}

			isMessagePrinted = true;
		}

		if (!isMessagePrinted) {
			out.print("Unrecognized error!");
		}
		out.print("</div>");

	}

	public boolean getDetail() {
		return detail;
	}

	public void setDetail(boolean detail) {
		this.detail = detail;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}
	
	/**
	 * Return Localized Resource Manager for preferable locale from session
	 * (Constant.ATTRIBUTE_PREFERABLE_LOCALE). If it isn't specified Locale will
	 * be taken from request
	 * 
	 * @param request
	 *            ;
	 * @return LRManager - LocalizedResourceManager;
	 * 
	 */
	protected LocalizedResourceManager getLocalizedResourceManager(
			HttpServletRequest request) {

		HttpSession session = request.getSession(false);
		Object localeObj = null;
		if (session != null) {
			localeObj = session
					.getAttribute(Constant.ATTRIBUTE_PREFERABLE_LOCALE);
		}

		Locale locale = null;
		if (localeObj != null) {
			locale = new Locale((String)localeObj);
		} else {
			
			// Get Locale from request
			locale = request.getLocale();
		}

		// Create LocalizedResourceManager to get localized error messages
		LocalizedResourceManager LRManager = new LocalizedResourceManager(
				locale);

		return LRManager;
	}
}
